package com.newly.center.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.newly.center.business.service.CheckRecordService;
import com.newly.center.business.service.MQTTBlackListService;
import com.newly.center.business.service.MQTTDeviceService;
import com.newly.center.business.service.VehicleService;
import com.newly.common.base.entity.R;
import com.newly.common.base.entity.auth.ICurrentTenant;
import com.newly.common.base.entity.business.Dto.CarDto;
import com.newly.common.base.entity.business.Dto.CarListDto;
import com.newly.common.base.entity.business.Dto.CheckRecordDto;
import com.newly.common.base.entity.business.Po.CheckRecord;
import com.newly.common.base.entity.business.Po.Vehicle;
import com.newly.common.base.entity.business.Vo.CheckRecordVo;
import com.newly.common.base.entity.business.Vo.DetailsVo;
import com.newly.common.base.entity.business.Vo.ExcelVehicle;
import com.newly.common.base.entity.business.Vo.RecordVo;
import com.newly.common.base.exception.NewlyException;
import com.newly.common.core.utils.CopyUtil;
import com.newly.common.core.utils.PageUtil;
import com.newly.common.mapper.business.CompanyMapper;
import com.newly.common.mapper.business.VehicleMapper;
import com.newly.common.mapper.sys.AuthEntityMapper;
import com.newly.common.mapper.sys.TenantMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @anthor sbq
 * @date 2021/10/26 14:25
 */
@Service("GovVehicleService")
public class VehicleServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> implements VehicleService {

    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private AuthEntityMapper entityMapper;
    @Autowired
    private CheckRecordService checkRecordService;
    @Autowired
    private MQTTBlackListService mqttBlackListService;
    @Autowired
    private MQTTDeviceService mqttDeviceService;

    @Override
    public PageUtil getPage(ICurrentTenant currentTenant, CarListDto carListDto) {

        Page<Vehicle> page = new Page<>(carListDto.getPageNum(), carListDto.getPageSize());
        //获取数据范围
        //List<Long> entityIds = DataAuth.getEntityIds(currentUser, EntityTypeEnum.车辆.getCode());
        /*if (ObjectUtil.isEmpty(entityIds))
            return new PageUtil(page);*/
        QueryWrapper<Vehicle> q = new QueryWrapper<>();
        //q.lambda().in(Vehicle::getId, entityIds);
        q.lambda().like(StringUtils.isNotBlank(carListDto.getVehicleNumber()), Vehicle::getVehicleNumber, carListDto.getVehicleNumber());
        q.lambda().like(StringUtils.isNotBlank(carListDto.getVehicleUser()), Vehicle::getContactsName, carListDto.getVehicleUser());
        q.lambda().eq(StringUtils.isNotBlank(carListDto.getVehicleType()), Vehicle::getVehicleType, carListDto.getVehicleType());
        q.lambda().eq(Vehicle::getIsDeleted, 0);
        q.lambda().eq(Vehicle::getBlackName, carListDto.getIsBlack());
        q.lambda().orderByAsc(Vehicle::getId);
        //分页查询车辆记录
        page = this.page(page, q);
        return new PageUtil(page);
    }

    @Override
    public DetailsVo<Vehicle> getCarDetails(String vehicleNumber, Integer offset) {

        String startTime = DateUtil.offsetDay(DateUtil.date(), -offset).toString();
        DetailsVo<Vehicle> detailsVo = new DetailsVo<>();
        Vehicle vehicle = this.getOne(new QueryWrapper<Vehicle>().lambda().eq(Vehicle::getVehicleNumber, vehicleNumber).eq(Vehicle::getIsDeleted, 0));
        detailsVo.setEntity(vehicle);
        CheckRecordDto checkRecordDto = new CheckRecordDto().setCarNumbers(Arrays.asList(vehicleNumber)).setStartTime(startTime).setEndTime(DateUtil.now());
        List<CheckRecord> checkRecordList = this.checkRecordService.getListByCondition(checkRecordDto);
        List<CheckRecordVo> checkRecordVoList = CopyUtil.copyList(checkRecordList, CheckRecordVo.class);
        checkRecordVoList = this.checkRecordService.cover(checkRecordVoList);
        List<RecordVo> recordVos = new ArrayList<>();
        for (CheckRecordVo checkRecordVo : checkRecordVoList) {
            RecordVo recordVo = new RecordVo()
                    .setId(checkRecordVo.getId())
                    .setSiteName(checkRecordVo.getSiteName())
                    .setRatio(checkRecordVo.getOverRate())
                    .setOverweightType(checkRecordVo.getOverweightType())
                    .setTime(new DateTime(checkRecordVo.getCreateTime()).toString());
            recordVos.add(recordVo);
        }
        detailsVo.setRecordVoList(recordVos);
        return detailsVo;
    }

    @Override
    public void edit(CarDto carDto) {

        Vehicle vehicle = BeanUtil.copyProperties(carDto, Vehicle.class);
        //设置黑名单需下发网关，另开新接口
//        vehicle.setBlackName(null);
        vehicle.setCreateTime(DateUtil.now());
        this.updateById(vehicle);

    }

    @Override
    public void save(CarDto carDto, ICurrentTenant currentTenant) {

        Vehicle vehicle = BeanUtil.copyProperties(carDto, Vehicle.class);
        vehicle.setCreateTime(DateUtil.now());
        this.save(vehicle);
        //设置黑名单需下发网关，另开新接口
//        vehicle.setBlackName(carDto.getBlackName());
        //保存权限实体
/*        AuthEntityPo authEntityPo = new AuthEntityPo();
        authEntityPo.setEntityId(vehicle.getId().toString());
        authEntityPo.setType(AuthConstant.AuthEntityType.SITE.getCode());
        authEntityPo.setCreateTime(DateUtil.date());
        this.entityMapper.insert(authEntityPo);*/
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean batchSave(List<ExcelVehicle> list, ICurrentTenant currentTenant) {
        List<Vehicle> vehicles = new ArrayList<>();
        for (ExcelVehicle carDto : list) {
            Vehicle vehicle = BeanUtil.copyProperties(carDto, Vehicle.class, "blackName", "state");
            vehicle.setBlackName("是".equals(carDto.getBlackName()) ? 1 : 2);
            vehicle.setState("正常".equals(carDto.getState()) ? 0 : 1);
            vehicle.setCreateTime(DateUtil.now());
            vehicle.setCreateUser(currentTenant.getUserId());
            vehicles.add(vehicle);
        }
        try {
            this.saveBatch(vehicles);
        } catch (Exception e) {
            e.printStackTrace();
            throw new NewlyException("车辆信息入库失败");
        }
        //保存权限实体
/*        vehicles.forEach(vehicle -> {
            AuthEntityPo authEntityPo = new AuthEntityPo();
            authEntityPo.setEntityId(vehicle.getId().toString());
            authEntityPo.setType(EntityTypeEnum.车辆.getCode());
            authEntityPo.setCreateTime(DateUtil.date());
            try {
                entityMapper.insert(authEntityPo);
            } catch (Exception e) {
                e.printStackTrace();
                throw new NewlyException("保存权限实体失败");
            }
        });*/

        return true;
    }

    @Override
    public R delete(Long[] ids) {
        List<Vehicle> vehicleList = this.list(new QueryWrapper<Vehicle>().lambda().in(Vehicle::getId, Arrays.asList(ids)));
        if (vehicleList.size() == 0)
            throw new NewlyException("车辆id有误，请联系管理员！");
        List<String> carNumbers = vehicleList.stream().map(Vehicle::getVehicleNumber).collect(Collectors.toList());
        //查询记录表是否存在记录
        List<CheckRecord> checkRecordList = this.checkRecordService.list(new LambdaQueryWrapper<CheckRecord>().in(CheckRecord::getCarNum, carNumbers));
        if (checkRecordList.size() > 0)
            return R.fail(1, "车辆存在过车记录，不能删除！");
        vehicleList = vehicleList.stream().filter(t -> t.getIsDeleted() == 0).peek(t -> t.setIsDeleted(1)).collect(Collectors.toList());
        this.updateBatchById(vehicleList);
        //删除权限实体对应记录
/*        List<AuthEntityPo> entityPos = this.entityMapper.selectList(new QueryWrapper<AuthEntityPo>().lambda().in(AuthEntityPo::getEntityId, Arrays.asList(ids)));
        if (ObjectUtil.isEmpty(entityPos))
            throw new NewlyException("车辆id没有绑定到权限实体表，请联系管理员！");
        List<Integer> entityIds = entityPos.stream().map(AuthEntityPo::getId).collect(Collectors.toList());
        this.entityMapper.deleteBatchIds(entityIds);*/
        return R.ok("删除成功");
    }

    @Override
    public boolean repeat(String carNumber) {
        List<Vehicle> vehicles = this.list(new QueryWrapper<Vehicle>().lambda().eq(Vehicle::getVehicleNumber, carNumber).eq(Vehicle::getIsDeleted, 0));
        return vehicles.size() > 0;
    }

    @Override
    public boolean setBlackName(String id, String carNumber, Boolean isBlackName) {
        Vehicle vehicle = this.getById(Long.parseLong(id));
//        if(isBlackName){
//            if(vehicle.getBlackName()==0||vehicle.getBlackName()==2){
//                //多网关同步添加
//                Map<String,String> addResult= new HashMap<>();
//                JSONArray livingGateway = mqttDeviceService.getLivingGateway();
//                for(Object item : livingGateway){
//                    Map<String, String> data = (Map<String, String>) item;
//                    String gatewayId = data.get("id");
//                    R response = mqttBlackListService.addBlackList(gatewayId, new String[]{carNumber});
//                    if(response.getCode()!=0){
//                        return false;
//                    }
//                    JSONArray indexList = JSONUtil.parseObj(response.getData()).getJSONArray("index");
//                    String index = indexList.getStr(0);
//                    if(vehicle.getBlackIndex()==null){
//                        vehicle.setBlackIndex(index);
//                    }
//                    //如果返回的索引则将原有的修改掉并删除新增的索引
//                    if(!index.equals(vehicle.getBlackIndex())){
//
//                    }
//                }
//            }
////            else {
////                //多网关同步修改
////                JSONArray livingGateway = mqttDeviceService.getLivingGateway();
////                int blackIndex = Integer.parseInt(vehicle.getBlackIndex());
////                for(Object item : livingGateway){
////                    Map<String, String> data = (Map<String, String>) item;
////                    String gatewayId = data.get("id");
////                    R response = mqttBlackListService.modifyBlackList(gatewayId,blackIndex,carNumber);
////                    if(response.getCode()!=0){
////                        return false;
////                    }
////                    vehicle.setBlackIndex(blackIndex+"");
////                }
////            }
//        }else {
//            //多网关同步删除
//            JSONArray livingGateway = mqttDeviceService.getLivingGateway();
//            int blackIndex = Integer.parseInt(vehicle.getBlackIndex());
//            for(Object item : livingGateway){
//                Map<String, String> data = (Map<String, String>) item;
//                String gatewayId = data.get("id");
//                R response = mqttBlackListService.deleteBlackList(gatewayId, blackIndex);
//                if(response.getCode()!=0){
//                    return false;
//                }
//            }
//        }

        if (isBlackName) {
            vehicle.setBlackName(1);
        } else {
            vehicle.setBlackName(2);
        }
        boolean update = this.updateById(vehicle);
        return update;
    }
}
